#!/usr/bin
# -*- coding: utf-8 -*-

def normalize(v, l=None):
    """ This function normalizes the vector v upon its length of the
    give length l if provided """
    if l:
        nv = l
    else:
        nv = norm(v)
    try:
        vu = (v[0]/nv, v[1]/nv, v[2]/nv)
    except:
        raise ValueError, "Can't normalize the given vector of norm " + str(nv)
    return vu

def vector(A, B):
    """ This function creates a vector from its origin and end points """
    return (B[0]-A[0], B[1]-A[1], B[2]-A[2])

def vec(a, b):
    """ This function computes the cross product a x b """
    c = (a[1]*b[2]-a[2]*b[1],
         b[0]*a[2]-b[2]*a[0],
         a[0]*b[1]-a[1]*b[0])
    return c 

def sca(a, b):
    """ This function computes the scalar product a . b """
    return a[0]*b[0] + a[1]*b[1] + a[2]*b[2]

def norm(a):
    """ This function computes the norm of the vector a """
    return mqsrt(a[0]**2 + a[1]**2 + a[2]**2)











# ------------------------------------------------------------------------------
def enrichConnectivity(args):
    # ndsC from domC
    for domIdC in args["domsC"]:
        args["ndsCFromDomC"].append({}) # on est obligé de créer a priori
    for domIdC, elsIdsC in enumerate(args["domsC"]):
        for elIdC in elsIdsC:
            ndsIdsC = args["elsC"][elIdC]
            for ndIdC in ndsIdsC:
                try:
                    a = args["ndsCFromDomC"][domIdC][ndIdC]
                except:
                    args["ndsCFromDomC"][domIdC][ndIdC] = None
        args["ndsCFromDomC"][domIdC] = tuple(args["ndsCFromDomC"][domIdC].keys())

    # elsC from ndC
    for ndIdC in args["ndsC"]:
        args["elsCFromNdC"].append({})
    for elIdC, ndsIdsC in enumerate(args["elsC"]):
        for ndIdC in ndsIdsC:
            try:
                a = args["elsCFromNdC"][ndIdC][elIdC]
            except:
                args["elsCFromNdC"][ndIdC][elIdC] = None

    # domsC from elC
    for elIdC in args["elsC"]:
        args["domCFromElC"].append(None)
    for domIdC, elsIdsC in enumerate(args["domsC"]):
        for elIdC in elsIdsC:
            args["domCFromElC"][elIdC] = domIdC

    # domsC from ndC
    for ndIdC in args["ndsC"]:
        args["domsCFromNdC"].append({})
    for elIdC, domIdC in enumerate(args["domCFromElC"]):
        ndsIdsC = args["elsC"][elIdC]
        for ndIdC in ndsIdsC:
            try:
                a = args["domsCFromNdC"][ndIdC][domIdC]
            except:
                args["domsCFromNdC"][ndIdC][domIdC] = None

    for ndIdC in xrange(len(args["ndsC"])):
        args["elsCFromNdC"][ndIdC] = tuple(args["elsCFromNdC"][ndIdC].keys())
        args["domsCFromNdC"][ndIdC] = tuple(args["domsCFromNdC"][ndIdC].keys())



# ------------------------------------------------------------------------------
def buildDomainsBoundaries(args):
    args["topDomsEdgesC"] = []
    
    for topDom in args["topDomsC"]:
        topDom.append(topDom[-1])
        for i in xrange(len(topDom)-1):
            A, B = topDom[i], topDom[i+1]
            A, B = args["ndsC"][A], args["ndsC"][B]
            AB = (B[0]-A[0], B[1]-A[1], B[2]-A[2])
            nAB = msqrt(AB[0]**2 + AB[1]**2 + AB[2]**2)
            try:
                uAB = (AB[0]/nAB, AB[1]/nAB, AB[2]/nAB)
            except:
                raise ValueError, "edge de longueur nulle"



# ==============================================================================
if __name__ == "__main__":
    from math import sqrt as msqrt

    EPSILON = 1.0e-6
    ABAQUS_MAX_ARGS_PER_LINE = 16

    fileName = "maillage2.dat"

    # Données brutes du fichier
    ndsC, ndsC2U, ndsU2C = [], [], {}
    elsC, elsC2U, elsU2C = [], [], {}
    domsC, domsC2U, domsU2C = [], [], {}
    topDomsC, topDomsC2U, topDomsU2C = [], [], {}

    # Connectivité complémentaire
    ndsCFromDomC = []
    elsCFromNdC = []
    domCFromElC = []
    domsCFromNdC = []

    # Données rassemblées dans dictionnaire (accès par adresse)
    args = {"ndsC":ndsC,
            "ndsC2U":ndsC2U,
            "ndsU2C":ndsU2C,
            "elsC":elsC,
            "elsC2U":elsC2U,
            "elsU2C":elsU2C,
            "domsC":domsC,
            "domsC2U":domsC2U,
            "domsU2C":domsU2C,
            "topDomsC":topDomsC,
            "topDomsC2U":topDomsC2U,
            "topDomsU2C":topDomsU2C,
            "ndsCFromDomC":ndsCFromDomC,
            "elsCFromNdC":elsCFromNdC,
            "domCFromElC":domCFromElC,
            "domsCFromNdC":domsCFromNdC}

    readGlobalNumFile(fileName, args)
    enrichConnectivity(args)

    buildDomainsBoundaries(args)

    print "ndsC\n", args["ndsC"]
    print "ndsU2C\n", args["ndsU2C"]
    print "ndsC2U\n", args["ndsC2U"]

    print "\n\n"

    print "elsC\n", args["elsC"]
    print "elsU2C\n", args["elsU2C"]
    print "elsC2U\n", args["elsC2U"]

    print "\n\n"

    print "domsC\n", args["domsC"]
    print "domsU2C\n", args["domsU2C"]
    print "domsC2U\n", args["domsC2U"]

    print "\n\n"

    print "topDomsC\n", args["topDomsC"]
    print "topDomsU2C\n", args["topDomsU2C"]
    print "topDomsC2U\n", args["topDomsC2U"]

    print "\n\n"

    print "ndsCFromDomC\n", args["ndsCFromDomC"]
    print "elsCFromNdC\n", args["elsCFromNdC"]
    print "domCFromElC\n", args["domCFromElC"]
    print "domsCFromNdC\n", args["domsCFromNdC"]
